﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;

using SistemaCenterQuimPost.Plantillas;
using SistemaCenterQuimPost.Control;
using SistemaCenterQuimPost.Reportes; //usado para imprimir la venta

namespace SistemaCenterQuimPost.UI.PostCajero
{
    public partial class frmRecibirPago : SistemaCenterQuimPost.UI.PostCajero.frmGestionClientes
    {
        //------------ATRIBUTOS-------------------
        private DataSet2 centerQuimDs;  //atributos necesario para acceder a la bD
        private DataSet2TableAdapters.CajasTableAdapter cajaTa;
        private DataSet2TableAdapters.PostTableAdapter postTa;
        private DataSet3TableAdapters.MovimientosTableAdapter movimientosClientesTa;

        private string turno; //almacena el turno actual

        private int codCaja; //almacena el codigo de la caja actual.


        //-----------CONSTRUCTORES---------------
        public frmRecibirPago()
        {
            InitializeComponent();

            centerQuimDs = new DataSet2();  //se inicializan los atributos necesarios para conectarme a la base de datos.
            cajaTa = new DataSet2TableAdapters.CajasTableAdapter();
            movimientosClientesTa = new DataSet3TableAdapters.MovimientosTableAdapter();
            postTa = new DataSet2TableAdapters.PostTableAdapter();
            this.turno = ""; //se inicializa el turno con un string arbitrario.

            this.codCaja = 0; //se inicializa el codCaja con un valor arbitrario.

            removerControles();  //se remueve los controles heredados que no necesitamos en esta interface, por diseño no se puede

            posicionarListBox(); //se posiciona los listBox, porque por herencia en el diseño no se puede.

            this.vaciarTextBox(); //deja vacio los campos para cargar nuevos datos.

        }


        //------------ESTADOS--------------------
        protected override void estEsperandoOperacion() //estado luego de realizar una busqueda exitosa, agregar o editar. Es decir con datos en vista.
        {
            System.Windows.Forms.Control[] controlesHabilitados = { this.txtDni, this.btnBusDni, this.txtApellido, this.btnBusApellido, this.btnAgregar, this.btnProcesar };
            System.Windows.Forms.Control[] controlesDeshabilitados = { this.txtNombre, this.txtCuit, this.txtProvincia, this.txtLocalidad, this.txtDireccion, this.txtTel, this.txtCel, this.txtEmail, this.txtDescuento, this.btnEditar};
            System.Windows.Forms.Control[] controlesVisibles = { };
            System.Windows.Forms.Control[] controlesInvisibles = { lstClientesApellidoNombre, this.lblErrorDni, this.lblErrorApellido, this.lblErrorNombre, this.lblErrorDireccion, lblError };

            habilitarControles(controlesHabilitados);
            deshabilitarControles(controlesDeshabilitados);
            visibleControles(controlesVisibles);
            invisibleControles(controlesInvisibles);

            if (refrescarResgClientes) //si hace falta actualizar el refrescarResgClientes se realiza
            {
                ejecutarHiloActualizarResgClientes();

            }

            errorProvider1.Clear();  //se borran los errores, si habian.

            txtDni.Focus();   //se deja el foco en txtDni

            estadoDelFormulario = "estEsperandoOperacion";

        }
        
        //--------------METODOS VARIOS--------------------
        public void verificarCajaAbierta()  //Verifica que exista caja y que esté abierta, es llamado desde el menu.
        {
            try
            {
                int codUltimaCaja = 0;  //almacenará el código de la última caja, si existe.

                codUltimaCaja = Convert.ToInt32(cajaTa.ScalarQueryCaja()); //busca la ultima caja si hay registros.

                cajaTa.FillByNroCaja(centerQuimDs.Cajas, codUltimaCaja); //obtiene todos los datos de la ultima caja


                if (centerQuimDs.Cajas[0].estado == "A") // si la caja está abierta 
                {
                    this.turno = centerQuimDs.Cajas[0].turno; //se establecen el turno y codCaja

                    this.codCaja = codUltimaCaja;

                    this.Show();  //muestra la interface.

                }

                else   //Si existe caja y está cerrada, informamos que no se procesar ingresos hasta que habra alguna.
                {
                    MessageBox.Show("No existe caja abierta, en la que pueda registrar pagos.", "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);
                    
                    this.Close(); //Cerramos el form instanciado y colocado en la coleccion de menu, de esta forma desligamos del menu.
            
                }
            }

            catch (IndexOutOfRangeException)  //excepcion cuando no encuentra registro en la base de datos caja.
            {
                MessageBox.Show("Aún no se han abierto ninguna caja, por lo tanto no puede registrar pagos.", "INFORMES", MessageBoxButtons.OK, MessageBoxIcon.Information);

                this.Close(); //Cerramos el form instanciado y colocado en la coleccion de menu, de esta forma desligamos del menu.
                       
            }

            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

            }
        }
        
        private void removerControles()   //Eliminar los controles que heredé pero que no los voy a usar.
        {
            this.Controls.Remove(this.groupBox2);
            this.Controls.Remove(this.groupBox3);
            this.Controls.Remove(this.lblErrorDni);
            this.Controls.Remove(this.lblErrorApellido);
            this.Controls.Remove(this.lblNombre);
            this.Controls.Remove(this.txtNombre);
            this.Controls.Remove(this.lblErrorNombre);
            this.Controls.Remove(this.lblCuit);
            this.Controls.Remove(this.txtCuit);
            this.Controls.Remove(this.lblProvincia);
            this.Controls.Remove(this.txtProvincia);
            this.Controls.Remove(this.lblLocalidad);
            this.Controls.Remove(this.txtLocalidad);
            this.Controls.Remove(this.lblDireccion);
            this.Controls.Remove(this.txtDireccion);
            this.Controls.Remove(this.lblErrorDireccion);
            this.Controls.Remove(this.lblTel);
            this.Controls.Remove(this.txtTel);
            this.Controls.Remove(this.lblCel);
            this.Controls.Remove(this.txtCel);
            this.Controls.Remove(this.lblEmail);
            this.Controls.Remove(this.txtEmail);
            this.Controls.Remove(this.lblDescuento);
            this.Controls.Remove(this.txtDescuento);
            this.Controls.Remove(this.btnAgregar);
            this.Controls.Remove(this.btnEditar);
            this.Controls.Remove(this.lblAgregar);
            this.Controls.Remove(this.lblEditar);
            
        }

        private void posicionarListBox()  //usado para colocar a los lstBox en su lugar, ya que por herencia en t.Diseño no se puede.
        {
            lstClientesApellidoNombre.Location = new Point(256, 126);

        }

        protected override void resguardarClienteActual() //Guarda los valores de los textBox en array resgClienteActual, luego de una busqueda exitosa.
        {

        }

        protected override void deshacerCambios()  //usado cuando en estado editar o agregar, se arrepiente (no se apreta en procesar) y se vuelve a estado esperandoOperacion.
        {

        }

        protected override void vaciarTextBox() //Se deja en blanco todos los textBox, usado en estado cuando inicia el formulario y cuando termina de procesar algo.
        {
            this.lblDniValor.Text = "";
            this.lblApellidoNombreValor.Text = "";
            this.lblDireccionValor.Text = "";
            this.lblSaldoValor.Text = "";
            this.txtConcepto.Text = "";
            this.txtImporte.Text = "0";

        }


        protected override void cargarClientePorDni(string unDni) //busca cliente con dni (una coincidencia) encontrado en el oHiloFiltrarDni y lo carga en los textBox.
        {
            try
            {
                //(ALE)HACER EL FILL O COMO LO LLAMES ACA ABAJO
                //clientesTa.FillByClientes(centerQuimDs,unDni);
                clientesTa.FillByDni(clientesDs.Clientes, unDni);

                //ARREGLAR ESTO. Se rellena los textBox con la consulta encontrada.
                lblDniValor.Text = clientesDs.Clientes[0].dni;

                lblApellidoNombreValor.Text = clientesDs.Clientes[0].apellidoyNombre;
                lblDireccionValor.Text = clientesDs.Clientes[0].direccion;
                lblSaldoValor.Text = clientesDs.Clientes[0].saldo.ToString();



                //...
                //..FALTAN LOS OTROS. ACORDATE QUE ESTE ES EL DE CAJERO, TIENE POCOS CONTROLES.

            }
            catch (IndexOutOfRangeException)
            {

            }
            catch (Exception ex)
            {
                //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                //Si llega a ocurrir algún error grave se cierra el formulario 
                this.Close();
            }
        }

        protected override void cargarClientesPorApellidoNombre(string unApellidoNombre)  //busca el cliente por nombreApellido en la base de datos y lo carga en los textbox.
        {
            //(ALE) HACER EL FILL O COMO LO LLAMES ACA ABAJO
            clientesTa.FillByApellidoNombre(clientesDs.Clientes, unApellidoNombre);

            //ARREGLAR ESTO. Se rellena los textBox con la consulta encontrada.
            lblDniValor.Text = clientesDs.Clientes[0].dni;

            lblApellidoNombreValor.Text = clientesDs.Clientes[0].apellidoyNombre;
            lblDireccionValor.Text = clientesDs.Clientes[0].direccion;
            lblSaldoValor.Text = clientesDs.Clientes[0].saldo.ToString();

            //...
            //..FALTAN LOS OTROS. ACORDATE QUE ESTE ES EL DE CAJERO, TIENE POCOS CONTROLES.


        }

        //Se redefine el comportamiento de este boton
        protected override void procesar() //se encapsulo en un método para usar cuando se presiona Enter con los textBox
        {

            if (formularioValido())
            {
                try
                {
                    agregarPago();

                }
                catch (IndexOutOfRangeException)
                {

                }
                catch (Exception ex)
                {
                    //Por cualquier otra excepcion se informa el error, en este caso es un error grave.
                    MessageBox.Show("La conexión a la base de datos no fué exitosa.\n\n Comuniquese con su desarrollador para solucionar el problema.\n\n" + ex.Message, "ERROR GRAVE - ACCESO A BASE DE DATO", MessageBoxButtons.OK, MessageBoxIcon.Error);

                    //Si llega a ocurrir algún error en estado agregar 
                    this.Close();
                }

            }
            else
            {
                informarExistenciaError();
            }


        }

        private void agregarPago()
        {
            DialogResult result = MessageBox.Show("¿Está seguro que desea recibir el pago del cliente?.", "CONFIRMACION RECEPCION DE PAGO", MessageBoxButtons.YesNo, MessageBoxIcon.Question);

            if (result == DialogResult.Yes)
            {
                actualizarCaja();
                
                actualizarSaldo();

                agregarMovimiento();

                //Se muestra un mje de confirmación.
                MessageBox.Show("Pago recibido con exito!!!", "AVISO", MessageBoxButtons.OK, MessageBoxIcon.Information);

                refrescarResgClientes = true;  //como se agregó un pago el resgClientes está desactualizado. (en el saldo).

                vaciarTextBox(); //

                estEsperandoOperacion(); //Luego de insertar un cliente se vuelve al estado esperando operación. Para que pueda editarlo o eliminarlo rapidamente.

                imprimirReciboPago(); //se imprime un recibo de pago.
            }
        }

        
        private void actualizarCaja() //por el pago, aumenta la caja final y el campo pagos.
        {
            cajaTa.FillByNroCaja(centerQuimDs.Cajas, this.codCaja);
            centerQuimDs.Cajas[0].pagos += Math.Round(Convert.ToDouble(txtImporte.Text),2);
            centerQuimDs.Cajas[0].cajaFinal += Math.Round(Convert.ToDouble(txtImporte.Text), 2);

            cajaTa.Update(centerQuimDs.Cajas);

        }

        private void agregarMovimiento() //se inserta el pago en el movimiento del cliente
        {
            int mov = Convert .ToInt32 ( movimientosClientesTa.ScalarQueryUltimoMovimiento()); //buscamos el ultimo movimiento ingresado
            mov++; //lo incrementamos para que coincida con el ultimo movimiento a ingresar
            postTa.Fill(centerQuimDs.Post); //obtenemos el unico post cargado

            movimientosClientesTa.InsertQueryMovimiento(lblDniValor.Text, Convert.ToDateTime(obtenerFechaActual()), "Pago en Post: "+centerQuimDs .Post [0].nombre.ToString () + " Mov. Nª: "+ mov.ToString () , "Reduccion Cta. Cte", Convert.ToDecimal(txtImporte.Text));
        }

        private void actualizarSaldo() //por el pago el saldo del cliente disminuye.
        {
            clientesTa.FillByDni(clientesDs.Clientes, lblDniValor.Text);//buscamos cliente
            clientesDs.Clientes[0].saldo -= Math.Round(Convert.ToDouble(txtImporte.Text), 2); //incrementamos saldo
            clientesTa.Update(clientesDs.Clientes);
        }

        private string obtenerFechaActual()  //Dato necesario para el alta de venta
        {
            frmPlantillaPadre unFrm = (frmPlantillaPadre)this.MdiParent;
            return unFrm.getFechaActual();
        }

        private void imprimirReciboPago()
        {
            int ultimo = Convert .ToInt32 ( movimientosClientesTa.ScalarQueryUltimoMovimiento()); //buscamos el ultimo movimiento

            //creamos una instancia del tipo CrystalReports que habiamos creado y le asignamos a su crvVenta la tabla instanciada y parametros necesarios.
            crPago  unCrPago= new crPago();

            //buscamos todos los datos del ultimo movimiento
            movimientosClientesTa.FillByIdMovimiento(clientesDs.Movimientos  , ultimo);

            //buscamos estado del cliente
            clientesTa.FillByDni(clientesDs.Clientes, clientesDs.Movimientos[0].dni);

            //cargamos parametros
            unCrPago.SetParameterValue("unaDireccion", centerQuimDs.Post [0].dirección .ToString ());
            unCrPago.SetParameterValue("unTelefono", centerQuimDs.Post[0].telefono .ToString());
            unCrPago.SetParameterValue("unaFecha", clientesDs.Movimientos[0].fecha.ToString("d"));
            unCrPago.SetParameterValue("unMovimiento", "0000"+clientesDs .Movimientos [0].idMovimiento .ToString ());
            unCrPago.SetParameterValue("unCliente", clientesDs .Clientes [0].apellidoyNombre .ToString ());
            unCrPago.SetParameterValue("unaSuma", clientesDs.Movimientos[0].importe.ToString());
            unCrPago.SetParameterValue("unConcepto", clientesDs.Movimientos[0].concepto .ToString());
            unCrPago.SetParameterValue("unSaldo", clientesDs.Clientes [0].saldo .ToString());

            FrmReportePago unFrmReportePago = new FrmReportePago();
            unFrmReportePago.crvPago.ReportSource = unCrPago;

            unFrmReportePago.ShowDialog();
        }

        protected override bool formularioValido()
        {

            validarConcepto();

            validarImporte();

            validarClienteyConexion();


            if ((errorProvider1.GetError(txtConcepto) == "") & (errorProvider1.GetError(txtImporte) == "") & (errorProvider1.GetError(btnProcesar) == ""))
            {
                return true;
            }
            else
            {
                return false;
            }
        }

        private void validarConcepto()
        {
            if (txtConcepto.Text == "")
            {
                errorProvider1.SetError(txtConcepto, "");

            }else
            {

                errorProvider1.SetError(txtConcepto, new ValidarDatos().validarLongitud("Concepto", txtConcepto.Text, 41));
            
            }
        }

        private void validarImporte()
        {
            errorProvider1.SetError(txtImporte, new ValidarDatos().validarMoneda("Importe", txtImporte.Text));
        }

        private void validarClienteyConexion()
        {
            errorProvider1.SetError(btnProcesar, this.validarConexionInternet() + validarExistenciaCliente());
        }

       
        private string validarExistenciaCliente() //valida que si se desea vender a cuenta corriente, exista un cliente diferente a CONSUMIDOR FINAL.
        {
            if (lblApellidoNombreValor.Text == "")
            {
                return "Debe seleccionar un cliente para registrar un pago del mismo\n\n";
            }
            else
            {
                return "";
            }
        }

        private string validarConexionInternet()
        {
            try
            {
                System.Net.IPHostEntry host = System.Net.Dns.GetHostEntry("www.google.com");

                return "";
            }
            catch (Exception)
            {
                return "\nPara registrar un pago debe tener conexión a internet. \n Verifique la misma y vuelva a intentarlo.";

            }
        }
    
    
    }

    


}
